package socket.socket;


import socket.modle.ConnectedCallback;
import socket.modle.PlcInterface;
import socket.util.SLog;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Logger;


/**
 * Created by bpb on 2022/3/25
 */
public class SocketServerUtil implements PlcInterface {

    Logger log = Logger.getLogger("SocketServerUtil");
    private static volatile SocketServerUtil socketServerUtil;

    private ConnectedCallback callback; // socket连接状态上报
    private ServerSocket serverSocket; // 创建的socket服务器

    private ConcurrentHashMap<String, ClientSocketProxy> clientSockets = new ConcurrentHashMap<>();
    private int retryCount = 0; // socket服务器创建失败重试次数
    private int currentRetryCount = 0; // 当前重试的次数
    int port = 5500;

    public static SocketServerUtil getInstance() {
        if (socketServerUtil == null) {
            synchronized (SocketServerUtil.class) {
                if (socketServerUtil == null) {
                    socketServerUtil = new SocketServerUtil("Server");
                }
            }
        }
        return socketServerUtil;
    }

    public SocketServerUtil(String tag) {

    }

    @Override
    public PlcInterface init(ConnectedCallback callback, int retryCount) {
        this.callback = callback;
        this.retryCount = retryCount;
        return this;
    }

    @Override
    public void connect(Object... params) {
        if (serverSocket != null && !serverSocket.isClosed()) {
            return;
        }
        port = (int) params[0];
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                try {
                    serverSocket = new ServerSocket(port);
                } catch (IOException e) {
                    callback.onConnectedStatusChange("server",false, e, "创建服务器失败");
                    return;
                }
                SLog.getInstance().e_s("正在创建服务端口 " + port);
                while (!serverSocket.isClosed()) {
                    try {
                        // 有新的socket客户端连上
                        Socket socket = serverSocket.accept();
                        ClientSocketProxy proxy = new ClientSocketProxy(socket, callback);
                        clientSockets.put(proxy.socketKey, proxy);
                        proxy.start();
                        proxy.notifyConnectState();
                    } catch (IOException e) {
                        disConnect(e);
                    }
                }
                log.info("服务器端口 " + port + "  停止监听客户端");
            }
        };
        new Thread(runnable).start();
    }

    @Override
    public void sendData(String key, final byte[] data) {
        ClientSocketProxy p = clientSockets.get(key);
        if (p != null) {
            p.sendData(data);
        }
    }

    @Override
    public boolean isConnected() {
        return true;
    }

    @Override
    public void disConnect(Exception e) {

    }

    @Override
    public void destroy(String who) {
        ClientSocketProxy p = clientSockets.get(who);
        if (p != null) {
            clientSockets.remove(who);
            p.destroy();
        }
    }


}
